package response

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo/v4"
)

// CustomHTTPErrorHandler 自定义HTTP错误处理器
// 确保所有错误响应都遵循统一的Response格式
func CustomHTTPErrorHandler(err error, c echo.Context) {
	// 如果响应已经被写入，就不再处理
	if c.Response().Committed {
		return
	}

	var (
		code    = http.StatusInternalServerError
		message = "Internal Server Error"
	)

	// 处理Echo的HTTPError
	if he, ok := err.(*echo.HTTPError); ok {
		code = he.Code
		if m, ok := he.Message.(string); ok {
			message = m
		} else {
			message = fmt.Sprintf("%v", he.Message)
		}
	} else {
		// 处理其他类型的错误
		message = err.Error()
	}

	// 根据不同的HTTP状态码设置合适的错误消息
	switch code {
	case http.StatusNotFound:
		message = "Route not found"
	case http.StatusMethodNotAllowed:
		message = "Method not allowed"
	case http.StatusBadRequest:
		if message == "Bad Request" {
			message = "Invalid request"
		}
	case http.StatusUnauthorized:
		if message == "Unauthorized" {
			message = "Authentication required"
		}
	case http.StatusForbidden:
		if message == "Forbidden" {
			message = "Access denied"
		}
	case http.StatusRequestTimeout:
		message = "Request timeout"
	case http.StatusTooManyRequests:
		if message == "Too Many Requests" {
			message = "Rate limit exceeded"
		}
	case http.StatusInternalServerError:
		if message == "Internal Server Error" {
			message = "An internal error occurred"
		}
	case http.StatusBadGateway:
		message = "Bad gateway"
	case http.StatusServiceUnavailable:
		message = "Service temporarily unavailable"
	case http.StatusGatewayTimeout:
		message = "Gateway timeout"
	}

	// 使用统一的Response格式返回错误
	resp := &Response{
		Code:    code,
		Message: message,
	}

	// 发送JSON错误响应
	if !c.Response().Committed {
		if c.Request().Method == http.MethodHead {
			err = c.NoContent(code)
		} else {
			err = c.JSON(code, resp)
		}
		if err != nil {
			// 如果JSON响应失败，记录错误但不再尝试响应
			// 避免无限递归
			c.Logger().Error("Failed to send error response:", err)
		}
	}
}

// ErrorWithDetail 创建带详细信息的错误响应
func ErrorWithDetail(c echo.Context, code int, message string, detail interface{}) error {
	return c.JSON(code, &Response{
		Code:    code,
		Message: message,
		Detail:  detail,
	})
}

// ValidationError 创建验证错误响应
func ValidationError(c echo.Context, detail interface{}) error {
	return ErrorWithDetail(c, http.StatusBadRequest, "Validation failed", detail)
}
